//
// Created by shen on 2024/6/23.
//

#include "VaoSample.h"
#include "GLUtils.h"

#define VERTEX_POS_SIZE       3 // x, y and z
#define VERTEX_COLOR_SIZE     4 // r, g, b, and a

#define VERTEX_POS_INDX       0 //shader layout loc
#define VERTEX_COLOR_INDX     1 //shader layout loc
void VaoSample::Init() {
    const char vShaderStr[]="";
    const char fShaderStr[] ="";

    GLfloat vertices[4 *(VERTEX_POS_SIZE + VERTEX_COLOR_SIZE )] =
            {
                    -0.5f,  0.5f, 0.0f,       // v0
                    1.0f,  0.0f, 0.0f, 1.0f,  // c0
                    -0.5f, -0.5f, 0.0f,       // v1
                    0.0f,  1.0f, 0.0f, 1.0f,  // c1
                    0.5f, -0.5f, 0.0f,        // v2
                    0.0f,  0.0f, 1.0f, 1.0f,  // c2
                    0.5f,  0.5f, 0.0f,        // v3
                    0.5f,  1.0f, 1.0f, 1.0f,  // c3
            };
    //顶点索引
    GLushort  indices[6]={0,1,2,0,2,3};
    m_ProgramObj = GLUtils::CreateProgram(vShaderStr, fShaderStr, m_VertexShader, m_FragmentShader);


    glGenBuffers(2,m_VboIds);
    glBindBuffer(GL_ARRAY_BUFFER,m_VboIds[0]);
    glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,m_VboIds[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //创建
    // Generate VAO Id
    glGenVertexArrays(1,&m_VaoId);
    glBindVertexArray(m_VaoId);


    glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[1]);

    //
    glEnableVertexAttribArray(VERTEX_POS_INDX);
    glEnableVertexAttribArray(VERTEX_COLOR_INDX);

    glVertexAttribPointer(VERTEX_POS_INDX,VERTEX_POS_SIZE,
                          GL_FLOAT,
                          GL_FALSE,
                          (sizeof(GLfloat)*(VERTEX_POS_SIZE+VERTEX_COLOR_SIZE)),
                          (const void *)0);

    glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE,
                          GL_FLOAT, GL_FALSE, (sizeof(GLfloat)*(VERTEX_POS_SIZE+VERTEX_COLOR_SIZE)),
                          (const void *)(VERTEX_POS_SIZE *sizeof(GLfloat)));

    glBindVertexArray(GL_NONE);

}

void VaoSample::Draw(int screenW, int screenH) {

    if (m_ProgramObj == 0) return;

    glUseProgram(m_ProgramObj);

    glBindVertexArray(m_VaoId);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *) 0);
    // Return to the default VAO
    glBindVertexArray(GL_NONE);

}

void VaoSample::Destroy()
{
    if (m_ProgramObj)
    {
        glDeleteProgram(m_ProgramObj);
        glDeleteBuffers(2, m_VboIds);
        glDeleteVertexArrays(1, &m_VaoId);
        m_ProgramObj = GL_NONE;
    }

}

